//
// Description: 291. 蒙德里安的梦想
// Created by Loading on 2022/6/4.
//

#include <bits/stdc++.h>

using namespace std;

constexpr int N = 12, M = 1 << N;

// dp[i][j] 表示第 i 列，j 状态下的所有方案数，注意使用 long long
/* 状态 j 为二进制，如果某行前一列与本列出现横向长方形，则此行对应二进制为 1，否则为 0 */
long long dp[N][M];
// 状态是否合法
bool st[M];

/* 状压DP */
int main() {
    int n, m;
    while (cin >> n >> m && n != 0 && m != 0) {
        // 预处理状态数组
        for (int i = 0; i < 1 << n; ++i) {
            st[i] = true;
            // 表示纵向连续 0 的个数
            int cnt = 0;
            for (int j = 0; j < n; ++j) {
                if (i >> j & 1) {
                    if (cnt % 2) {
                        st[i] = false;
                    }
                    cnt = 0;
                } else {
                    ++cnt;
                }
            }
            if (cnt % 2) {
                st[i] = false;
            }
        }

        memset(dp, 0, sizeof dp);
        // 第一列无前一列，只有一种方案
        dp[0][0] = 1;
        for (int i = 1; i <= m; ++i) {
            // 枚举此列状态
            for (int j = 0; j < 1 << n; ++j) {
                // 枚举前一列状态
                for (int k = 0; k < 1 << n; ++k) {
                    // 两个状态不能出现重叠，前一列不能出现纵向填充不满的情况
                    if (!(j & k) && st[j | k]) {
                        dp[i][j] += dp[i - 1][k];
                    }
                }
            }
        }

        // 最后一列的下一列，状态 0 的情况即为答案
        cout << dp[m][0] << endl;
    }

    return 0;
}